use std::sync::Arc;

use crate::models::Message;
use crate::AppState;
use axum::extract::Path;
use axum::extract::State;
use axum::http::StatusCode;
use axum::response::Html;
use axum::response::IntoResponse;
use axum::Json;
use serde::Deserialize;
use serde::Serialize;
use serde_json::json;
use crate::models::MessageEvent;
use log::{error, info, warn, debug, trace};
use std::borrow::Cow; // 用于处理UTF-8转换的临时字符串引用

/// 邮件附件数据结构（Base64编码内容）
#[derive(Debug, Serialize, Deserialize)]
pub struct EmailAttachment {
    pub filename: String,
    pub content_type: String,
    pub content: String, // Base64编码的附件二进制内容
}

/// 邮件创建请求数据结构
#[derive(Debug, Serialize, Deserialize)]
pub struct EmailData {
    pub from: String,
    pub to: Vec<String>,
    pub cc: Option<Vec<String>>,
    pub bcc: Option<Vec<String>>,
    pub subject: String,
    pub text: Option<String>,
    pub html: Option<String>,
    pub attachments: Option<Vec<EmailAttachment>>,
}

/// 创建新邮件（接收JSON请求，生成EML并存储）
pub async fn create_message(
    State(state): State<Arc<AppState>>,
    axum::Json(email_data): axum::Json<EmailData>,
) -> impl IntoResponse {
    debug!(
        "接收邮件创建请求: 发件人={}, 收件人={:?}, 主题={}, 附件数={}",
        email_data.from,
        email_data.to,
        email_data.subject,
        email_data.attachments.as_ref().map_or(0, |atts| atts.len())
    );

    trace!("开始构建EML内容（处理MIME结构）");
    let eml_content = build_eml(&email_data);
    trace!("EML构建完成，总长度={}字节", eml_content.len());

    let eml_bytes = eml_content.into_bytes();
    let message = match Message::from(&eml_bytes) {
        Ok(msg) => {
            debug!(
                "EML解析成功: 解析后邮件ID={:?}, 发件人字段={:?}",
                msg.id, msg.sender
            );
            msg
        }
        Err(e) => {
            error!(
                "EML解析失败: 错误原因={}, 请求参数预览={:?}",
                e, email_data
            );
            return (
                StatusCode::BAD_REQUEST,
                Json(json!({
                    "error": "Failed to parse email content",
                    "details": e.to_string()
                })),
            );
        }
    };

    let stored_msg = match state.storage.write() {
        Ok(mut storage) => {
            let msg = storage.add(message.clone());
            info!(
                "邮件存储成功: 最终邮件ID={:?}, 原始发件人={}, 存储时间={:?}",
                msg.id, email_data.from, msg.created_at
            );
            msg
        }
        Err(e) => {
            error!(
                "邮件存储失败: 获取写锁错误={}, 邮件主题={}",
                e, email_data.subject
            );
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                Json(json!({
                    "error": "Failed to access email storage",
                    "details": "Storage lock acquisition failed"
                })),
            );
        }
    };

    let event = MessageEvent {
        event_type: "add".to_owned(),
        message: stored_msg.clone(),
    };
    match serde_json::to_string(&event) {
        Ok(event_str) => {
            if state.channel.send(event_str).is_ok() {
                debug!("邮件事件广播成功: 邮件ID={:?}", stored_msg.id);
            } else {
                warn!(
                    "邮件事件广播失败: 通道可能已关闭（邮件已存储，但实时通知未触发），邮件ID={:?}",
                    stored_msg.id
                );
            }
        }
        Err(e) => {
            error!(
                "邮件事件序列化失败: 错误={}, 邮件ID={:?}",
                e, stored_msg.id
            );
        }
    }

    (
        StatusCode::CREATED,
        Json(json!({
            "message": "Email received and stored successfully",
            "id": stored_msg.id,
            "created_at": stored_msg.created_at
        })),
    )
}

/// 构建符合RFC 822标准的EML内容
fn build_eml(email_data: &EmailData) -> String {
    let mut eml = String::new();

    trace!("开始构建EML头部字段");
    eml.push_str(&format!("From: {}\r\n", email_data.from));
    eml.push_str(&format!("To: {}\r\n", email_data.to.join(", ")));

    if let Some(cc) = &email_data.cc {
        eml.push_str(&format!("Cc: {}\r\n", cc.join(", ")));
        trace!("EML添加Cc字段: 收件人列表={:?}", cc);
    }
    if let Some(bcc) = &email_data.bcc {
        eml.push_str(&format!("Bcc: {}\r\n", bcc.join(", ")));
        trace!("EML添加Bcc字段: 收件人列表={:?}", bcc);
    }

    eml.push_str(&format!("Subject: {}\r\n", email_data.subject));
    eml.push_str("MIME-Version: 1.0\r\n");
    trace!("EML头部构建完成");

    let has_attachments = email_data.attachments.as_ref().map_or(false, |a| !a.is_empty());
    let has_html = email_data.html.is_some();
    debug!(
        "EML内容结构决策: 含附件={}, 含HTML={}, 最终MIME类型={}",
        has_attachments,
        has_html,
        if has_attachments || has_html { "multipart/mixed" } else { "text/plain" }
    );

    if has_attachments || has_html {
        let boundary = format!("----=_Part_{}", uuid::Uuid::new_v4().simple());
        eml.push_str(&format!("Content-Type: multipart/mixed; boundary=\"{}\"\r\n", boundary));
        eml.push_str("\r\nThis is a multipart message in MIME format.\r\n");

        eml.push_str(&format!("--{}\r\n", boundary));
        if let Some(html) = &email_data.html {
            eml.push_str("Content-Type: text/html; charset=\"UTF-8\"\r\n");
            eml.push_str("Content-Transfer-Encoding: 7bit\r\n\r\n");
            eml.push_str(html);
            eml.push_str("\r\n");
            trace!("EML添加HTML内容: 长度={}字节", html.len());

            if let Some(text) = &email_data.text {
                eml.push_str(&format!("--{}\r\n", boundary));
                eml.push_str("Content-Type: text/plain; charset=\"UTF-8\"\r\n");
                eml.push_str("Content-Transfer-Encoding: 7bit\r\n\r\n");
                eml.push_str(text);
                eml.push_str("\r\n");
                trace!("EML添加纯文本内容: 长度={}字节", text.len());
            }
        } else if let Some(text) = &email_data.text {
            eml.push_str("Content-Type: text/plain; charset=\"UTF-8\"\r\n");
            eml.push_str("Content-Transfer-Encoding: 7bit\r\n\r\n");
            eml.push_str(text);
            eml.push_str("\r\n");
            trace!("EML添加纯文本内容: 长度={}字节", text.len());
        }

        if let Some(attachments) = &email_data.attachments {
            for (idx, att) in attachments.iter().enumerate() {
                eml.push_str(&format!("--{}\r\n", boundary));
                eml.push_str(&format!(
                    "Content-Type: {}; name=\"{}\"\r\n",
                    att.content_type, att.filename
                ));
                eml.push_str(&format!(
                    "Content-Disposition: attachment; filename=\"{}\"\r\n",
                    att.filename
                ));
                eml.push_str("Content-Transfer-Encoding: base64\r\n\r\n");
                eml.push_str(&att.content);
                eml.push_str("\r\n");
                trace!(
                    "EML添加附件[{}]: 文件名={}, 内容长度={}字节, 类型={}",
                    idx, att.filename, att.content.len(), att.content_type
                );
            }
        }

        eml.push_str(&format!("--{}--\r\n", boundary));
    } else {
        eml.push_str("Content-Type: text/plain; charset=\"UTF-8\"\r\n");
        eml.push_str("Content-Transfer-Encoding: 7bit\r\n\r\n");
        if let Some(text) = &email_data.text {
            eml.push_str(text);
            trace!("EML添加纯文本内容: 长度={}字节", text.len());
        }
        eml.push_str("\r\n");
    }

    eml
}

/// 查询所有邮件（返回完整列表）
pub async fn index(State(state): State<Arc<AppState>>) -> Json<Vec<Message>> {
    let storage = match state.storage.read() {
        Ok(s) => s,
        Err(e) => {
            error!("查询所有邮件失败: 获取读锁错误={}", e);
            return Json(Vec::new());
        }
    };

    let messages = storage.list().to_vec();
    trace!("查询所有邮件成功: 总数量={}封", messages.len());
    Json(messages)
}

/// 获取邮件原始源码（text/plain格式返回）
pub async fn show_source(
    Path(id): Path<usize>,
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    debug!("接收邮件源码查询请求: 邮件ID={}", id);

    let storage = match state.storage.read() {
        Ok(s) => s,
        Err(e) => {
            error!(
                "邮件源码查询失败: 获取读锁错误={}, 邮件ID={}",
                e, id
            );
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                [("Content-Type", "text/plain;charset=utf-8")],
                "Failed to access email storage".to_string()
            );
        }
    };

    // 修复1：直接获取Message，通过id字段是否为None判断邮件是否存在
    let message = storage.get(id);
    if message.id.is_none() {
        warn!("邮件源码查询失败: 邮件ID={}不存在", id);
        return (
            StatusCode::NOT_FOUND,
            [("Content-Type", "text/plain;charset=utf-8")],
            format!("Email with ID {} not found", id)
        );
    }
    let source_str: Cow<'_, str> = String::from_utf8_lossy(&message.source);
    info!(
        "邮件源码查询成功: 邮件ID={:?}, 源码长度={}字节",
        message.id, message.source.len()
    );
    (
        StatusCode::OK,
        [("Content-Type", "text/plain;charset=utf-8")],
        source_str.into_owned(),
    )
}

/// 删除单封邮件（按ID删除）
pub async fn delete(
    Path(id): Path<usize>,
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    info!("接收邮件删除请求: 邮件ID={}", id);

    let mut storage = match state.storage.write() {
        Ok(s) => s,
        Err(e) => {
            error!(
                "邮件删除失败: 获取写锁错误={}, 邮件ID={}",
                e, id
            );
            return StatusCode::INTERNAL_SERVER_ERROR;
        }
    };

    // 修复2：通过Message.id是否为None判断存在性，移除is_none()调用
    let existing_msg = storage.get(id);
    if existing_msg.id.is_none() {
        warn!("邮件删除失败: 邮件ID={}不存在", id);
        return StatusCode::NOT_FOUND;
    }

    storage.remove(id);
    info!("邮件删除成功: 邮件ID={}", id);
    StatusCode::OK
}

/// 获取邮件纯文本内容
pub async fn show_plain(
    Path(id): Path<usize>,
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    debug!("接收邮件纯文本查询请求: 邮件ID={}", id);

    let storage = match state.storage.read() {
        Ok(s) => s,
        Err(e) => {
            error!(
                "纯文本查询失败: 获取读锁错误={}, 邮件ID={}",
                e, id
            );
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                [("Content-Type", "text/plain;charset=utf-8")],
                "Failed to access email storage".to_string()
            );
        }
    };

    // 修复3：直接获取Message，通过id字段判断存在性
    let message = storage.get(id);
    if message.id.is_none() {
        warn!("纯文本查询失败: 邮件ID={}不存在", id);
        return (
            StatusCode::NOT_FOUND,
            [("Content-Type", "text/plain;charset=utf-8")],
            format!("Email with ID {} not found", id)
        );
    }

    let plain_content = match &message.plain {
        Some(content) => {
            info!(
                "纯文本查询成功: 邮件ID={:?}, 内容长度={}字节",
                message.id, content.len()
            );
            content.clone()
        }
        None => {
            warn!("纯文本查询失败: 邮件ID={:?}无纯文本内容", message.id);
            return (
                StatusCode::NO_CONTENT,
                [("Content-Type", "text/plain;charset=utf-8")],
                "Email has no plain text content".to_string()
            );
        }
    };

    (
        StatusCode::OK,
        [("Content-Type", "text/plain;charset=utf-8")],
        plain_content,
    )
}

/// 获取邮件HTML内容
pub async fn show_html(
    Path(id): Path<usize>,
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    debug!("接收邮件HTML查询请求: 邮件ID={}", id);

    let storage = match state.storage.read() {
        Ok(s) => s,
        Err(e) => {
            error!(
                "HTML查询失败: 获取读锁错误={}, 邮件ID={}",
                e, id
            );
            return (
                StatusCode::INTERNAL_SERVER_ERROR,
                [("Content-Type", "text/html;charset=utf-8")],
                "Failed to access email storage".to_string()
            );
        }
    };

    // 修复4：直接获取Message，通过id字段判断存在性
    let message = storage.get(id);
    if message.id.is_none() {
        warn!("HTML查询失败: 邮件ID={}不存在", id);
        return (
            StatusCode::NOT_FOUND,
            [("Content-Type", "text/html;charset=utf-8")],
            format!("Email with ID {} not found", id)
        );
    }

    let html_content = match &message.html {
        Some(content) => {
            info!(
                "HTML查询成功: 邮件ID={:?}, 内容长度={}字节",
                message.id, content.len()
            );
            content.clone()
        }
        None => {
            warn!("HTML查询失败: 邮件ID={:?}无HTML内容", message.id);
            return (
                StatusCode::NO_CONTENT,
                [("Content-Type", "text/html;charset=utf-8")],
                "Email has no HTML content".to_string()
            );
        }
    };

    (
        StatusCode::OK,
        [("Content-Type", "text/html;charset=utf-8")],
        html_content,
    )
}


pub async fn show_eml(
    Path(id): Path<usize>,
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    (
        StatusCode::OK,
        [("Content-Type", "message/rfc822")],
        state.storage.read().unwrap().get(id).source,
    )
}

pub async fn download_attachment(
    Path((id, cid)): Path<(usize, String)>,
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    for attachment in &state.storage.read().unwrap().get(id).attachments {
        if attachment.cid == cid {
            return (
                StatusCode::OK,
                [(
                    "Content-Disposition",
                    format!("attachment; filename=\"{}\"", attachment.filename),
                )],
                attachment.body.clone(),
            );
        }
    }

    (
        StatusCode::OK,
        [("Content-Type", "message/rfc822".to_string())],
        vec![],
    )
}

pub async fn show_json(Path(id): Path<usize>, State(state): State<Arc<AppState>>) -> Json<Message> {
    Json(state.storage.read().unwrap().get(id))
}

pub async fn delete_all(State(state): State<Arc<AppState>>) -> Html<&'static str> {
    state.storage.write().unwrap().delete_all();
    Html("Ok")
}
